<?php

namespace Tasker\Models;

class ProjectsModel extends BaseModel
{

	public function getAllProjects(array $where=array())
	{
		return $this->connection->project()->where($where);
	}

	public function getOpenProjects(array $where=array())
	{
		$where['closed'] = 'no';
		return $this->getAllProjects($where);
	}

	public function getPublicProjects($userID = 0, array $where=array())
	{
		$memberIn = array();
		foreach ($this->connection->project_member()->select('project_id')->where('user_id', $userID) as $p)
		{
			$memberIn[] = $p['project_id'];
		}
		return $this->getOpenProjects($where)->where("public = 'yes'" . (count($memberIn) > 0 ? "OR id IN (" . implode(',', $memberIn) . ")" : ""));
	}

	public function getUserProjects($userId, array $where=array())
	{
		return $this->getOpenProjects($where)
				->where('id', $this->connection->project_member()
						->select('project_id')->where('user_id', $userId))
				->where($where);
	}

	public function getRoles(array $where=array())
	{
		return $this->connection->project_role()->where($where)->order('priority');
	}

	public function getRole(array $where)
	{
		return $this->connection->project_role[$where];
	}

	public function getPermissions(array $where=array())
	{
		return $this->connection->project_permission()->where($where);
	}

	public function getPermission(array $where)
	{
		return $this->connection->project_permission[$where];
	}

	public function getPermissionsInRolesArray()
	{
		$permissionsInRoles = array();
		foreach ($this->connection->project_permission_role() as $permissionRole)
		{
			$permissionsInRoles[$permissionRole['project_role_id']][] = $permissionRole['project_permission_id'];
		}
		return $permissionsInRoles;
	}

	public function savePermissions($permissions)
	{
		if (is_array($permissions) || $permissions instanceof \Traversable)
		{
			try
			{
				//$this->connection->transaction = 'BEGIN';
				$this->connection->project_permission_role()->delete();
				foreach ($permissions as $role => $perms)
				{
					foreach ($perms as $permission)
					{
						$this->connection->project_permission_role()->insert(array('project_role_id' => $role, 'project_permission_id' => $permission));
					}
				}
				//$this->connection->transaction = 'COMMIT';
				return true;
			} catch (\Exception $e)
			{
				//$this->connection->transaction = 'ROLLBACK';
				return false;
			}
		}
		return false;
	}

	public function addRole($values)
	{
		$n_values = array(
			'name' => $values['name'],
			'role' => \Nette\Utils\Strings::webalize($values['name']),
			'priority' => $values['priority'] + 1,
		);
		$affected = $this->connection->project_role()->insert($n_values);
		if ($affected === FALSE)
		{
			return false;
		} else
		{
			$this->connection->project_role()->where('priority >= ' . $n_values['priority'] . ' AND id <> ' . $affected['id'])->update(array('priority' => new \NotORM_Literal('priority+1')));
			return true;
		}
	}

	public function editRole($values)
	{
		$values = (array) $values;
		$role = $this->connection->project_role[$values['id']];
		if ($role['priority'] == $values['priority'] + 1) // not changed
		{
			unset($values['priority']);
			$affected = $this->connection->project_role[$values['id']]->update($values);
		} else // changed
		{
			if ($values['priority'] > $role['priority'])
				$values['priority']--;
			$this->connection->project_role()->where('priority > ' . $role['priority'])->update(array('priority' => new \NotORM_Literal('priority-1')));
			$this->connection->project_role()->where('priority > ' . $values['priority'])->update(array('priority' => new \NotORM_Literal('priority+1')));

			$values['priority']++;
			$affected = $this->connection->project_role[$values['id']]->update($values);
		}
		if ($affected === FALSE)
		{
			return false;
		}
		return true;
	}

	public function deleteRole($id)
	{
		$role = $this->connection->project_role[$id];
		$affected = $this->connection->project_role[$id]->delete();
		if ($affected === FALSE)
		{
			return false;
		} else
		{
			$this->connection->project_role()->where('priority > ' . $role['priority'])->update(array('priority' => new \NotORM_Literal('priority-1')));
			return true;
		}
	}

	public function getMilestones(array $where=array())
	{
		return $this->connection->milestone()->where($where);
	}

	public function getMilestone($where=array())
	{
		return $this->connection->milestone[$where];
	}

	public function addMilestone($values)
	{
		$values = (array) $values;
		$tasks = $values['tasks'];
		unset($values['tasks'], $values['id']);
		$milestone = $this->connection->milestone()->insert($values);
		foreach ($tasks as $task => $isInMilestone)
		{
			if ($isInMilestone)
			{
				$id = $milestone['id'];
			} else
			{
				$id = null;
			}
			$this->connection->task[$task]->update(array('milestone_id' => $id));
		}
		return $milestone;
	}

	public function editMilestone($values)
	{
		$values = (array) $values;
		$tasks = $values['tasks'];
		unset($values['tasks']);
		$affected = $this->connection->milestone[$values['id']]->update($values);
		foreach ($tasks as $task => $isInMilestone)
		{
			if ($isInMilestone)
			{
				$id = $values['id'];
			} else
			{
				$id = null;
			}
			$this->connection->task[$task]->update(array('milestone_id' => $id));
		}
		return $affected;
	}

}
